<template>
  <el-dialog :title="title" :visible.sync="visible" class="dialog-md" append-to-body @close="visible = false">
    <el-form ref="formRef" :model="form" :rules="rules" label-width="100px" v-loading="loading">
      <el-form-item label="上级菜单" prop="parent_id">
        <tree-select
          v-model="form.parent_id"
          :options="menuOptions"
          :normalizer="normalizer"
          show-count
          placeholder="选择上级菜单" />
      </el-form-item>
      <el-form-item label="菜单类型" prop="type">
        <el-radio-group v-model="form.type">
          <el-radio label="M">目录</el-radio>
          <el-radio label="C">菜单</el-radio>
          <el-radio label="F">按钮</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="菜单图标" v-if="form.type !== 'F'">
        <el-popover placement="bottom-start" width="460" trigger="click">
          <IconSelect ref="iconSelect" @selected="iconSelected" :active-icon="form.icon" />
          <el-input slot="reference" v-model="form.icon" placeholder="点击选择图标" readonly>
            <icon-show :icon="form.icon" slot="prefix" v-if="form.icon" />
            <i class="el-icon-search" slot="prefix" v-else />
          </el-input>
        </el-popover>
      </el-form-item>
      <el-row>
        <el-col :span="12">
          <el-form-item label="菜单名称" prop="name">
            <el-input v-model="form.name" placeholder="请输入菜单名称" maxlength="64" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="显示排序" prop="list_sort">
            <el-input-number v-model="form.list_sort" controls-position="right" :min="0" class="w-full"/>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type !== 'F'">
          <el-form-item prop="is_external">
            <span slot="label">
              <el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
                <i class="el-icon-question"></i>
              </el-tooltip>
              是否外链
            </span>
            <el-radio-group v-model="form.is_external">
              <el-radio label="1">是</el-radio>
              <el-radio label="0">否</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type !== 'F'">
          <el-form-item prop="url" :rules="[{ required: true, message: '路由地址不能为空'}]">
            <span slot="label">
              <el-tooltip
                content="访问的路由地址，如：`user`，如外网地址需内链访问则以`http(s)://`开头"
                placement="top">
                <i class="el-icon-question"></i>
              </el-tooltip>
              路由地址
            </span>
            <el-input v-model="form.url" placeholder="请输入路由地址" maxlength="250" />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type === 'C'">
          <el-form-item prop="component">
            <span slot="label">
              <el-tooltip content="访问的组件路径，如：`system/user/index`，默认在`views`目录下" placement="top">
                <i class="el-icon-question"></i>
              </el-tooltip>
              组件路径
            </span>
            <el-input v-model="form.component" placeholder="请输入组件路径" maxlength="250" />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type !== 'M'">
          <el-form-item prop="perms">
            <span slot="label">
              <el-tooltip
                content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasPerm('system:user:list')`)"
                placement="top">
                <i class="el-icon-question"></i>
              </el-tooltip>
              权限字符
            </span>
            <el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="128" />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type === 'C'">
          <el-form-item prop="query">
            <span slot="label">
              <el-tooltip content='访问路由的默认传递参数，如：`{"id": 1, "name": "ry"}`' placement="top">
                <i class="el-icon-question"></i>
              </el-tooltip>
              路由参数
            </span>
            <el-input v-model="form.query" placeholder="请输入路由参数" maxlength="250" />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type === 'C'">
          <el-form-item prop="is_cache">
            <span slot="label">
              <el-tooltip content="选择是则会被`keep-alive`缓存，需要匹配组件的`name`和地址保持一致" placement="top">
                <i class="el-icon-question"></i>
              </el-tooltip>
              是否缓存
            </span>
            <el-radio-group v-model="form.is_cache">
              <el-radio label="1">缓存</el-radio>
              <el-radio label="0">不缓存</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="form.type !== 'F'">
          <el-form-item prop="is_visible">
            <span slot="label">
              <el-tooltip content="选择隐藏则路由将不会出现在侧边栏，但仍然可以访问" placement="top">
                <i class="el-icon-question"></i>
              </el-tooltip>
              显示状态
            </span>
            <el-radio-group v-model="form.is_visible">
              <el-radio
                v-for="dict in dict.type.sys_show_hide"
                :key="dict.value"
                :label="dict.value"
              >{{dict.label}}</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item prop="status">
            <template slot="label">
              <el-tooltip content="选择停用则路由将不会出现在侧边栏，也不能被访问" placement="top">
                <i class="el-icon-question"></i>
              </el-tooltip>
              菜单状态
            </template>
            <el-radio-group v-model="form.status">
              <el-radio
                v-for="dict in dict.type.sys_normal_disable"
                :key="dict.value"
                :label="dict.value"
              >{{dict.label}}</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <div class="dialog-footer slot">
      <el-button type="primary" @click="handleSubmit" :loading="submitting" :disabled="loading">确 定</el-button>
      <el-button @click="visible = false">取 消</el-button>
    </div>
  </el-dialog>
</template>

<script>
  import IconSelect from '@/components/widgets/IconSelect'
  import IconShow from '@/components/widgets/IconShow'
  import { infoMenuApi, selectMenuApi, editMenuApi, addMenuApi } from '@/api/system/menu'

  export default {
    name: 'MenuForm',
    dicts: ['sys_normal_disable', 'sys_show_hide'],
    components: { IconSelect, IconShow },
    props: {
      value: Boolean,
      row: Object,
    },
    data() {
      return {
        title: '',
        loading: false,
        submitting: false,
        menuOptions: [],
        form: {
          name: undefined,
          parent_id: undefined,
          type: 'M',
          perms: undefined,
          icon: undefined,
          url: undefined,
          query: undefined,
          component: undefined,
          is_external: '0',
          is_cache: '1',
          is_visible: '1',
          status: '1',
          list_sort: '0',
          remark: undefined
        },
        rules:{
          parent_id: [{ required: true, message: '请选择上级菜单', trigger: 'change' }],
          type: [{ required: true, message: '请选择菜单类型', trigger: 'blur' }],
          name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
          list_sort: [{ required: true, message: '顺序不能为空', trigger: 'blur' }],
          status: [{ required: true, message: '请选择菜单状态', trigger: 'blur' }]
        }
      }
    },
    computed: {
      visible: {
        get() {
          return this.value
        },
        set(val) {
          this.$emit('input', val)
        }
      }
    },
    created() {
      this.init()
    },
    methods: {
      async init() {
        this.loading = true
        this.form.id = this.row?.id || undefined
        if (this.form.id) {
          this.title = '编辑菜单'
          await this.getRowData()
        } else {
          this.title = '添加菜单'
          this.form.parent_id = this.row?.parent_id || undefined
        }
        await this.getTreeSelect()
        this.loading = false
      },
      async handleSubmit() {
        this.$refs.formRef.validate(async valid=>{
          if(!valid || this.submitting) return
          this.submitting = true
          try {
            await this.$modal.confirm('确定提交表单数据？')
            if (this.form.id) {
              await editMenuApi(this.form)
            } else {
              await addMenuApi(this.form)
            }
            this.$emit('submit')
            this.$modal.msgSuccess('操作成功')
            this.visible = false
          } catch (e) {
            this.submitting = false
          }
        })
      },
      async getRowData() {
        try {
          const { info } = await infoMenuApi(this.form.id)
          this.form = this.dataToForm(this.form, info)
        } catch (error) {
          this.visible = false
        }
      },
      async getTreeSelect() {
        try {
          const { list } = await selectMenuApi()
          const menu = { id: 0, name: '主类目', children: [] }
          menu.children = this.listToTree(list)
          this.menuOptions.push(menu)
        } catch (e) {}
      },
      iconSelected(name) {
        this.form.icon = name
      },
      normalizer(node) {
        return {
          id: node.id,
          label: node.name,
          children: node.children && node.children.length ? node.children : undefined
        }
      }
    }
  }
</script>
